﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ITAP.ShprossesBuilder.Modelling;
using ITAP.ShprossesBuilder.Calculations;
using System.Drawing.Printing;
using ITAP.Core.Modelling;
using ITAP.Core.Calculations;

namespace ITAP.ShprossesBuilder.Editor
{
    public delegate void ModelPreviewChanged();

    public partial class ModelPreviewControl : UserControl
    {
        public event ModelPreviewChanged PreviewChanged;

        ITAP.Core.Calculations.ModelCoordinateConverter coordinateConverter = new ModelCoordinateConverter();

        private Render.DraftRender render;

        private ImageExportInfo currentInfo;

        public ImageExportInfo CurrentInfo
        {
            get { return currentInfo; }
            set { currentInfo = value; }
        }

        public ModelPreviewControl()
        {
            InitializeComponent();
            render = new ITAP.ShprossesBuilder.Render.DraftRender();
            dimensionsOptions.OptionsChanged += new DimensionsOptionsChanged(dimensionsOptions_OptionsChanged);
        }

        void dimensionsOptions_OptionsChanged()
        {
            this.UpdateModel();
        }

        public void ShowInfo(ImageExportInfo info)
        {
            this.currentInfo = info;
            this.UpdateModel();
            this.UpdateControls();
        }

        private void UpdateControls()
        {
            canUpdateModel = false;
            dimensionsOptions.ShowOptions(this.currentInfo.DimensionsPreferences);
            textBoxModelName.Text = this.currentInfo.Model.Name;
            checkBoxDisable.Checked = !this.currentInfo.Enabled;
            if (this.currentInfo.PageSettings == null)
            {
                checkBoxRotate.Enabled = false;
                checkBoxRotate.Checked = false;
            }
            else
            {
                checkBoxRotate.Enabled = true;
                if (this.currentInfo.PageSettings.Landscape)
                    checkBoxRotate.Checked = true;
                else
                    checkBoxRotate.Checked = false;
            }
            canUpdateModel = true;
        }

        private void UpdateModel()
        {
            if (this.currentInfo == null)
                return;

            if (!canUpdateModel)
                return;

            RectangleF rectangleToDraw;

            render.SetDimensionsPreferences(this.currentInfo.DimensionsPreferences);
            //this.currentInfo.Model.Update(this.currentInfo.DimensionsPreferences);

            RectangleF modelBoundingBox = this.currentInfo.Model.Model.BoundingBox;

            Image image = new Bitmap((int)modelBoundingBox.Width, (int)modelBoundingBox.Height);

            Graphics graphics = Graphics.FromImage(image);

            graphics.Clear(Color.White);
            coordinateConverter.UseAutoScale = true;
            ModelPoint center = new ModelPoint(modelBoundingBox.X + modelBoundingBox.Width / 2, 
                                               modelBoundingBox.Y + modelBoundingBox.Height / 2);
            render.Initialize(graphics,
                             (int)image.Width,
                             (int)image.Height,
                             modelBoundingBox,
                             coordinateConverter,
                             center);
            render.SetSizesFont(this.currentInfo.DimensionsPreferences.Font);
            modelBoundingBox = render.GetModelBoundingBoxAfterDrawing(this.currentInfo.Model, 
                                                                      image.Width, image.Height);
            center = new ModelPoint(modelBoundingBox.X + modelBoundingBox.Width / 2, 
                                    modelBoundingBox.Y + modelBoundingBox.Height / 2);
            image = new Bitmap((int)modelBoundingBox.Width, (int)modelBoundingBox.Height);

            graphics = Graphics.FromImage(image);
            graphics.Clear(Color.White);
            render.Initialize(graphics,
                             (int)image.Width,
                             (int)image.Height,
                             modelBoundingBox,
                             coordinateConverter,
                             center);
            render.SetSizesFont(this.currentInfo.DimensionsPreferences.Font);
            render.Visit(this.currentInfo.Model);

            Graphics panelPreviewGraphics = panelPreview.CreateGraphics();

            Rectangle rect = Rectangle.Empty;

            if (this.currentInfo.PageSettings == null)
                rectangleToDraw = coordinateConverter.ModelRectangleToScreenRectangle(modelBoundingBox, this.panelPreview.ClientRectangle.Width, this.panelPreview.ClientRectangle.Height, modelBoundingBox, center);
            else
            {
                SizeF pageSize = this.currentInfo.VisiblePageSize;
                if (this.currentInfo.PageSettings.Landscape)
                    pageSize = new SizeF(pageSize.Height, pageSize.Width);

                RectangleF pageRect = new RectangleF(new Point(0, 0), pageSize);

                rectangleToDraw = coordinateConverter.ModelRectangleToScreenRectangle(pageRect,
                                                                              this.panelPreview.Width,
                                                                              this.panelPreview.Height,
                                                                              pageRect,
                                                                              new ModelPoint(pageSize.Width / 2, pageSize.Height / 2));
            }            

            int width = (int)coordinateConverter.ModelMeasureToScreenMeasure(image.Width, 
                                                                             (int)rectangleToDraw.Width, 
                                                                             (int)rectangleToDraw.Height, 
                                                                             new RectangleF(0, 0, image.Width, image.Height));
            int height = (int)coordinateConverter.ModelMeasureToScreenMeasure(image.Height, 
                                                                              (int)rectangleToDraw.Width, 
                                                                              (int)rectangleToDraw.Height, 
                                                                              new RectangleF(0, 0, image.Width, image.Height));
            rect = new Rectangle((int)(rectangleToDraw.X + rectangleToDraw.Width / 2) - width / 2, 
                                 (int)(rectangleToDraw.Y + rectangleToDraw.Height / 2) - height / 2, 
                                 width, 
                                 height);
            panelPreviewGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            panelPreviewGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            panelPreviewGraphics.Clear(Color.Gray);
            panelPreviewGraphics.FillRectangle(Brushes.White, rectangleToDraw);
            panelPreviewGraphics.DrawImage(image, rect, 
                                            new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);

            panelPreviewGraphics.DrawRectangle(Pens.Black, Rectangle.Truncate(rectangleToDraw));
        }

        private void textBoxModelName_KeyDown(object sender, KeyEventArgs e)
        {
            this.currentInfo.Model.Name = textBoxModelName.Text;
            this.UpdateControls();
            if (this.PreviewChanged != null)
                this.PreviewChanged.Invoke();
            
        }

        private void panelPreview_Paint(object sender, PaintEventArgs e)
        {
            if(this.currentInfo != null)
                this.UpdateModel();
        }

        private void checkBoxDisable_CheckedChanged(object sender, EventArgs e)
        {
            this.currentInfo.Enabled = !checkBoxDisable.Checked;
            if (this.PreviewChanged != null)
                this.PreviewChanged.Invoke();
        }

        private void textBoxModelName_KeyPress(object sender, KeyPressEventArgs e)
        {
            this.currentInfo.Model.Name = textBoxModelName.Text;
            this.UpdateControls();
            if (this.PreviewChanged != null)
                this.PreviewChanged.Invoke();
        }

        private bool canUpdateModel = true;
        private void checkBoxRotate_CheckedChanged(object sender, EventArgs e)
        {
            this.currentInfo.PageSettings.Landscape = checkBoxRotate.Checked;            
            this.UpdateModel();
        }

        private void ModelPreviewControl_Resize(object sender, EventArgs e)
        {
            this.UpdateModel();
        }
    }
}
